package com.dtp.core.support.runnable;

import com.dtp.common.ApplicationContextHolder;
import com.dtp.common.timer.HashedWheelTimer;
import com.dtp.common.timer.Timeout;
import com.dtp.core.thread.DtpExecutor;
import com.dtp.core.timer.QueueTimeoutTimerTask;
import com.dtp.core.timer.RunTimeoutTimerTask;
import org.slf4j.MDC;

import java.util.concurrent.TimeUnit;

import static com.dtp.common.constant.DynamicTpConst.TRACE_ID;

/**
 * 动态线程池任务类
 *
 * @author yanhom
 * @since 1.0.4
 *
 * @remark muse
 */
public class DtpRunnable implements Runnable {
    private final Runnable runnable;    // 待执行的任务
    private final String taskName;      // 任务名称
    private final String traceId;       // 日志跟踪id
    private Timeout runTimeoutTimer;    // 运行超时计时器
    private Timeout queueTimeoutTimer;  // 队列超时计时器

    public DtpRunnable(Runnable runnable, String taskName) {
        this.runnable = runnable;
        this.taskName = taskName;
        this.traceId = MDC.get(TRACE_ID); // "traceId"
    }

    /** 开启队列超时任务 */
    public void startQueueTimeoutTask(DtpExecutor executor) {
        long queueTimeout = executor.getQueueTimeout(); // 获得任务队列执行超时时间
        if (queueTimeout <= 0) return;

        HashedWheelTimer hashedWheelTimer = ApplicationContextHolder.getBean(HashedWheelTimer.class);
        QueueTimeoutTimerTask queueTimeoutTimerTask = new QueueTimeoutTimerTask(executor, this);
        queueTimeoutTimer = hashedWheelTimer.newTimeout(queueTimeoutTimerTask, queueTimeout, TimeUnit.MILLISECONDS);
    }

    /** 取消队列超时任务 */
    public void cancelQueueTimeoutTask() {
        if (queueTimeoutTimer != null)
            queueTimeoutTimer.cancel();
    }

    /** 开启运行超时任务 */
    public void startRunTimeoutTask(DtpExecutor executor, Thread thread) {
        long runTimeout = executor.getRunTimeout();
        if (runTimeout <= 0) return;

        HashedWheelTimer hashedWheelTimer = ApplicationContextHolder.getBean(HashedWheelTimer.class);
        RunTimeoutTimerTask runTimeoutTimerTask = new RunTimeoutTimerTask(executor, this, thread);
        runTimeoutTimer = hashedWheelTimer.newTimeout(runTimeoutTimerTask, runTimeout, TimeUnit.MILLISECONDS);
    }

    /** 取消运行超时任务 */
    public void cancelRunTimeoutTask() {
        if (runTimeoutTimer != null) runTimeoutTimer.cancel();
    }

    @Override
    public void run() {runnable.run();}

    public String getTaskName() {return taskName;}
    public String getTraceId() {return traceId;}
}
